﻿namespace Example.Xml.Xsl.UnitTests
{
    using System;
    using System.Text;
    using System.Xml;
    using Xunit;

    public class StylesheetFacts
    {
        [Fact]
        public void ctor_Uri()
        {
            Assert.NotNull(new Stylesheet(new Uri("Stylesheet.Tests.xslt", UriKind.Relative)));
        }

        [Fact]
        public void ctor_UriNull()
        {
            Assert.Throws<ArgumentNullException>(() => new Stylesheet(null));
        }

        [Fact]
        public void op_Transform_IXPathNavigable()
        {
            var xml = new XmlDocument();
            xml.LoadXml("<foo/>");

            const string expected = "<html>FOO</html>";
            var actual = new Stylesheet(new Uri("Stylesheet.Tests.xslt", UriKind.Relative)).Transform(xml);

            Assert.Equal(expected, actual);
        }

        [Fact]
        public void op_Transform_IXPathNavigableNull()
        {
            var obj = new Stylesheet(new Uri("Stylesheet.Tests.xslt", UriKind.Relative));

            Assert.Throws<ArgumentNullException>(() => obj.Transform(null));
        }

        [Fact]
        public void op_Transform_IXPathNavigableNull_Encoding_Xhtml()
        {
            var obj = new Stylesheet(new Uri("Stylesheet.Tests.xhtml.xslt", UriKind.Relative));

            Assert.Throws<ArgumentNullException>(() => obj.Transform(null, Encoding.UTF32));
        }

        [Fact]
        public void op_Transform_IXPathNavigable_DocType()
        {
            var xml = new XmlDocument();
            xml.LoadXml("<foo/>");

            var expected = new StringBuilder();
            expected.AppendLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
            expected.Append("<html>FOO</html>");

            var actual = new Stylesheet(new Uri("Stylesheet.Tests.DocType.xslt", UriKind.Relative)).Transform(xml);

            Assert.Equal(expected.ToString(), actual);
        }

        [Fact]
        public void op_Transform_IXPathNavigable_EncodingNull_Xhtml()
        {
            var xml = new XmlDocument();
            xml.LoadXml("<foo/>");

            var obj = new Stylesheet(new Uri("Stylesheet.Tests.xhtml.xslt", UriKind.Relative));

            Assert.Throws<ArgumentNullException>(() => obj.Transform(xml, null));
        }

        [Fact]
        public void op_Transform_IXPathNavigable_Encoding_Xhtml()
        {
            var xml = new XmlDocument();
            xml.LoadXml("<foo/>");

            var expected = new StringBuilder();
            expected.AppendLine("<?xml version=\"1.0\" encoding=\"utf-32\"?>");
            expected.AppendLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
            expected.AppendLine("<html xml:lang=\"en\" lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">");
            expected.AppendLine("  <head>");
            expected.AppendLine("    <title>FOO</title>");
            expected.AppendLine("  </head>");
            expected.AppendLine("  <body>");
            expected.AppendLine("    <h1>FOO</h1>");
            expected.AppendLine("  </body>");
            expected.Append("</html>");

            var actual = new Stylesheet(new Uri("Stylesheet.Tests.xhtml.xslt", UriKind.Relative)).Transform(xml, Encoding.UTF32);

            Assert.Equal(expected.ToString(), actual);
        }

        [Fact]
        public void op_Transform_IXPathNavigable_Reuse()
        {
            var xml = new XmlDocument();
            xml.LoadXml("<foo/>");

            var stylesheet = new Stylesheet(new Uri("Stylesheet.Tests.xslt", UriKind.Relative));
            stylesheet.Transform(xml);

            const string expected = "<html>FOO</html>";
            var actual = stylesheet.Transform(xml);

            Assert.Equal(expected, actual);
        }

        [Fact]
        public void op_Transform_IXPathNavigable_Xhtml()
        {
            var xml = new XmlDocument();
            xml.LoadXml("<foo/>");

            var expected = new StringBuilder();
            expected.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            expected.AppendLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
            expected.AppendLine("<html xml:lang=\"en\" lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">");
            expected.AppendLine("  <head>");
            expected.AppendLine("    <title>FOO</title>");
            expected.AppendLine("  </head>");
            expected.AppendLine("  <body>");
            expected.AppendLine("    <h1>FOO</h1>");
            expected.AppendLine("  </body>");
            expected.Append("</html>");

            var actual = new Stylesheet(new Uri("Stylesheet.Tests.xhtml.xslt", UriKind.Relative)).Transform(xml);

            Assert.Equal(expected.ToString(), actual);
        }
    }
}